﻿#include <stdlib.h>
#include <stdint.h>
#include <mtPackTransform.h>
#include <QtCore>

extern "C" {

    static inline double point2mm(double w, double dpi) { return (w) * 25.4 / dpi; }
    static inline double mm2point(double w, double dpi) { return (w / 25.4 * dpi + .5); }
    //static inline double mm2point(double w, double dpi) { return (w / 25.4 * dpi); }

    MtPackTransformRet *MtPackTransformCallType
    MtPackTransform(const MtPackTransformParam *param)
    {
      if(param == nullptr || param->images == nullptr || param->imageCount == 0)
        return nullptr;

      size_t        retSz   = sizeof(MtPackTransformRet) +
                              sizeof(MtAffineMatrix) * param->imageCount;
      auto          ret     = (MtPackTransformRet *)malloc(retSz);
      Q_ASSERT(nullptr != ret);

      ret->matrix   = (MtAffineMatrix *)(ret + 1);
      ret->matCount = param->imageCount;

      // 计算view
      auto          *paper  = &param->paper;
      //double        wpappix = mm2point(paper->width, paper->xdpi);
      //double        hpappix = mm2point(paper->height, paper->ydpi);

      ret->view.left        = ret->view.top = 0;
      ret->view.right       = ((int64_t)mm2point(paper->width, paper->xdpi)) - 1;
      ret->view.bottom      = ((int64_t)mm2point(paper->height, paper->ydpi)) - 1;
      ret->view.xdpi        = paper->xdpi;
      ret->view.ydpi        = paper->ydpi;

      for(size_t i = 0; i < ret->matCount; i++)
      {
        auto        *img    = param->images + i;
        auto        *matrix = ret->matrix + i;

        // 统一到paper的dpi, 计算缩放比例
        double      scalex  = paper->xdpi / img->xdpi;
        double      scaley  = paper->ydpi / img->ydpi;

        // 原点缩放
        MtAffineFPoint center = { 0., 0., };
        MtBuildScaleMatrix2D(matrix, &center, scalex * img->scale, scaley * img->scale);

        // 原点缩放(需要先平移1个像素, 缩放后再还原)
        //MtBuildOffsetMatrix2D(matrix, 1, 1);
        //MtAffineMatrix mat;
        //MtAffineFPoint center = { 0., 0., };
        //MtBuildScaleMatrix2D(matrix, &center, scalex * img->scale, scaley * img->scale);
        //MtMulMatrix2D(matrix, matrix, &mat);
        //MtBuildOffsetMatrix2D(&mat, -1, -1);
        //MtMulMatrix2D(matrix, matrix, &mat);

        // 缩放后的像素pixel
        double      wpix    = mm2point(img->width, paper->xdpi) * img->scale;
        double      hpix    = mm2point(img->height, paper->ydpi) * img->scale;
        double      xpix    = mm2point(img->loc.x, paper->xdpi);
        double      ypix    = mm2point(img->loc.y, paper->ydpi);

        //水平镜像
        MtAffineMatrix mat;

        MtBuildMirrorHorMatrix2D(&mat,(wpix-1)/2);
        MtMulMatrix2D(matrix, matrix, &mat);

        // 原点旋转
        //MtAffineMatrix mat;
        MtBuildRotationMatrix2D(&mat, &center, img->rot, 1.);
        MtMulMatrix2D(matrix, matrix, &mat);

        // 根据转角进行平移
        if(img->rot == 0)
          MtBuildOffsetMatrix2D(&mat, xpix, ypix);
        else if(img->rot == 90)
          MtBuildOffsetMatrix2D(&mat, xpix, ypix + wpix);
        else if(img->rot == 180)
          MtBuildOffsetMatrix2D(&mat, xpix + wpix, ypix + hpix);
        else if(img->rot == 270)
          MtBuildOffsetMatrix2D(&mat, xpix + hpix, ypix);
        else
          MtBuildIdentityMatrix2D(&mat);

        MtMulMatrix2D(matrix, matrix, &mat);
      }
      return ret;
    }

    void MtPackTransformCallType
    MtPackTransformRelease(MtPackTransformRet *transform)
    {
      if(transform != nullptr)
        free(transform);
    }

}
